package com.service.totalauth.controller;

import com.service.config.utils.JsonXMLUtils;
import com.service.config.utils.RedisUtil;
import com.service.config.utils.Result;
import com.service.config.utils.StringUtils;
import com.service.totalauth.dao.CompanyInfoDao;
import com.service.totalauth.dao.ProgrammeApiBindDao;
import com.service.totalauth.dto.AuthorizationDto;
import com.service.totalauth.dto.QyAuth;
import com.service.totalauth.dto.QyAuthDto;
import com.service.totalauth.entity.CompanyInfo;
import com.service.totalauth.entity.ProgrammeApiBind;
import com.service.totalauth.service.AuthorizationUserService;
import com.service.totalauth.service.OrdinaryAuthService;
import com.service.totalauth.service.ThirdAuthorizationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import static com.service.config.constant.Constant.PARAMETER_NOT_FOUND;
import static com.service.config.constant.Constant.parameterNotFound;

/**
 * 授权终端用户认证表(AuthorizationUser)表控制层
 *
 * @author makejava
 * @since 2021-12-03 09:38:44
 */
@Controller
@RequestMapping("authorizationUser")
@Api(value = "授权终端用户认证接口", tags = "授权终端用户认证接口")
@Slf4j
public class AuthorizationUserController {
    /**
     * 服务对象
     */
    @Resource
    private AuthorizationUserService authorizationUserService;

    @Resource
    private OrdinaryAuthService ordinaryAuthService;
    @Resource
    private ThirdAuthorizationService thirdAuthorizationService;
    @Resource
    private ProgrammeApiBindDao programmeApiBindDao;
    @Resource
    private CompanyInfoDao companyInfoDao;
    @Resource
    private RedisUtil redisUtil;

    /**
     * 飞书/钉钉用户校验身份
     * @param
     * @return
     */
    @PostMapping(value = "checkLarkUser",produces="application/json")
    @ApiOperation(value = "飞书、钉钉、qq、支付宝用户校验身份")
    @ResponseBody
    public Result checkLarkUser(@RequestBody AuthorizationDto authorizationDto,
                                 @RequestParam(value = "secret",required = false) @ApiParam("钉钉小程序所需密钥") String secret,
                                 @RequestHeader(value = "token",required = false) @ApiParam("token令牌") String bAuthToken) throws Exception {
        String code = authorizationDto.getCode();
        if (!StringUtils.isEmpty(secret)) {
            if (redisUtil.exist(secret)){
                authorizationDto = JsonXMLUtils.json2obj(redisUtil.getValue(secret),AuthorizationDto.class);
                authorizationDto.setCode(code);
            }else {
                return Result.failure(PARAMETER_NOT_FOUND,"请重新刷新portal页面获取参数");
            }
        }
        //校验参数
        if (authorizationDto.getApmac() == null ||"".equals(authorizationDto.getApmac())
                ||authorizationDto.getSsid() == null ||"".equals(authorizationDto.getSsid())
                || authorizationDto.getProgrammeInfoBindId() == null || "".equals(authorizationDto.getProgrammeInfoBindId())) {
            return Result.failure(PARAMETER_NOT_FOUND,parameterNotFound);
        }
        return authorizationUserService.checkUser(bAuthToken,authorizationDto);
    }

    /**
     * 第三方授权终端用户
     * @param authorizationDto
     * @return
     */
    @ApiOperation(value = "第三方授权终端用户")
    @PostMapping("/authorizationU")
    @ResponseBody
    public Result authorizationUser(@RequestBody AuthorizationDto authorizationDto,
                                    @RequestParam("type") Integer type) throws Exception {
        return thirdAuthorizationService.setAuthorization(authorizationDto,type);
    }
    /**
     * 获取token
     * @param authorizationDto
     * @return
     */
    @ApiOperation(value = "获取token")
    @PostMapping("/getToken")
    @ResponseBody
    public Result getToken(@RequestBody AuthorizationDto authorizationDto,
                                    @RequestParam("type") @ApiParam("4--企业微信扫码授权认证 8--微信小程序分享认证") Integer type) throws Exception {
        return authorizationUserService.getUrlScheme(authorizationDto,type);
    }

    /**
     *
     * @param code
     * @param encryptedData
     * @param iv
     * @param programmeInfoBindId
     * @param redisToken 认证信息token
     * @param bAuthToken 微信小程序信息token
     * @return
     */
    @ApiOperation(value = "解密手机号")
    @PostMapping(value = "/decrypt")
    public Result decrypt(@RequestParam(value = "code") @ApiParam("微信二维码code") String code ,
                          @RequestParam(value = "nickName",required = false) @ApiParam("昵称") String nickName ,
                          @RequestParam(value = "programmeInfoBindId") @ApiParam("programmeInfoBindId") String programmeInfoBindId,
                          @RequestParam(value = "redisToken") @ApiParam("redisToken") String redisToken,
                          @RequestParam(value = "encryptedData",required = false) @ApiParam("encryptedData") String encryptedData,
                          @RequestParam(value = "iv",required = false) @ApiParam("iv") String iv,
                          @RequestParam(value = "token") @ApiParam("bAuthToken") String bAuthToken,
                          @RequestParam(value = "phoneCode")@ApiParam("phoneCode")String phoneCode) {
        try {
//            return authorizationUserService.decrypt(code,encryptedData,iv,flag,redisToken,bAuthToken);
            return authorizationUserService.decrypt(code,programmeInfoBindId,redisToken,bAuthToken,nickName,phoneCode);
        } catch (Exception e) {
            return Result.failure(1001, e.getMessage());
        }
    }

    /**
     * 获取缓存用户昵称及电话
     * @param
     * @return
     */
    @PostMapping(value = "getAuthorizationDetail",produces="application/json")
    @ApiOperation(value = "获取缓存用户昵称及电话")
    @ResponseBody
    public Result getAuthorizationDetail(@ApiParam("wxToken") String wxToken,
                                @ApiParam("redisToken") String redisToken,
                                @ApiParam("qyToken")String qyToken) throws Exception {
        if (wxToken==null || wxToken.equals("") || redisToken==null || redisToken.equals("")) {
            return Result.failure(PARAMETER_NOT_FOUND,parameterNotFound);
        }
        return authorizationUserService.getAuthorizationDetail(redisToken);
    }

    /**
     * 获取缓存用户信息、认证信息及企业微信用户信息
     * @param
     * @return
     */
    @GetMapping(value = "getCodeDetail",produces="application/json")
    @ApiOperation(value = "获取缓存用户信息、认证信息及企业微信用户信息")
    @ResponseBody
    public Result getCodeDetail(@ApiParam("wxToken") String wxToken,
                                @ApiParam("redisToken") String redisToken,
                                @ApiParam("code") String code,
                                @ApiParam("qyToken")String qyToken) throws Exception {
        if (wxToken==null || wxToken.equals("") || redisToken==null || redisToken.equals("")) {
            return Result.failure(PARAMETER_NOT_FOUND,parameterNotFound);
        }
        return authorizationUserService.getCodeDetail(wxToken,redisToken,qyToken,code);
    }

    /**
     * 弹出portal页面，点击跳转微信小程序，然后分享微信小程序到企业微信的一个聊天窗口，
     * 在聊天窗口中点击分享的链接，完成认证(这个方案中，参数是可以传递过来的，
     * 当然也可以不使用传递来的参数，直接使用无参数方案
     * 此方法为无参数方案
     * 企业微信授权(无参数方案,小程序内访问http://192.168.254.254/?wxauth=8&wxtoken=获取参数)
     * @param authorizationDto
     * @param bAuthToken
     * @return
     */
    @PostMapping(value = "checkQyWeiUser",produces = "application/json")
    @ApiOperation(value = "小程序内访问http://192.168.254.254/?wxauth=8&wxtoken=11 获取参数")
    @ResponseBody
    public Result checkQyWeiUser(@RequestBody AuthorizationDto authorizationDto,
                                      @RequestParam(value = "wxAuth",required = false) @ApiParam("wxAuth") String wxAuth,
                                      @RequestHeader(value = "token",required = false) @ApiParam("token令牌") String bAuthToken) throws Exception {
        return authorizationUserService.checkQyWeiUser(authorizationDto,bAuthToken,wxAuth);
    }
    /**
     * 华为云管直接接口访问
     * @return
     */
    @RequestMapping(value = "checkQyWeiUser1",method = RequestMethod.GET)
    @ApiOperation(value = "直接接口访问")
    public String checkQyWeiUser1(@RequestParam(value = "programmeInfoBindId",required = false) @ApiParam("programmeInfoBindId") String programmeInfoBindId,
                                  @RequestParam(value = "apmac",required = false) @ApiParam("apmac") String apmac,
                                  @RequestParam(value = "uaddress",required = false) @ApiParam("uaddress") String uaddress,
                                  @RequestParam(value = "umac",required = false) @ApiParam("umac") String umac,
                                  @RequestParam(value = "authType",required = false) @ApiParam("authType") String authType,
                                  @RequestParam(value = "lang",required = false) @ApiParam("lang") String lang,
                                  @RequestParam(value = "ssid",required = false) @ApiParam("ssid") String ssid,
                                  @RequestParam(value = "pushPageId",required = false) @ApiParam("pushPageId") String pushPageId,
                                  @RequestParam(value = "nodeIp",required = false) @ApiParam("nodeIp") String nodeIp,
                                  @RequestParam(value = "siteId",required = false) @ApiParam("siteId") String siteId,
                                  @RequestParam(value = "wxauth",required = false) @ApiParam("wxauth") String wxauth,
                                  @RequestParam(value = "wxtoken",required = false) @ApiParam("wxtoken") String wxtoken, Model map)  {
        if (StringUtils.isEmpty(wxauth) || StringUtils.isEmpty(wxtoken)) {
            return "redirect:https://cloudcampusapps.top/portalServer/qywxStaff?programmeInfoBindId=4641708316705792%3Fapmac%3D4cfacad82260&uaddress=192.168.1.128";
        }
        if (StringUtils.isEmpty(programmeInfoBindId) || StringUtils.isEmpty(uaddress) || StringUtils.isEmpty(umac) || StringUtils.isEmpty(ssid)) {
            return "error";
        }
        if (StringUtils.isEmpty(apmac)) {
            String[] split = programmeInfoBindId.split("\\?");
            programmeInfoBindId = split[0];
            String s = split[1];
            String[] split1 = s.split("=");
            apmac = split1[1];
        }
        AuthorizationDto authorizationDto = new AuthorizationDto();
        authorizationDto.setProgrammeInfoBindId(programmeInfoBindId);
        authorizationDto.setSsid(ssid);
        authorizationDto.setSiteId(siteId);
        authorizationDto.setApmac(apmac);
        authorizationDto.setDeviceMac(apmac);
        authorizationDto.setUmac(umac);
        authorizationDto.setUaddress(uaddress);
        Result result = ordinaryAuthService.checkQyWeiUser(authorizationDto, wxauth, wxtoken);
        map.addAttribute("result",result);
        return "Success";
    }
    /**
     * 企业微信授权上网
     * @param
     * @return
     */
    @PostMapping(value = "checkUserByQYWeChat",produces = "application/json")
    @ApiOperation(value = "企业微信授权上网")
    @ResponseBody
    public Result checkUserByQYWeChat(@RequestBody QyAuthDto authDto,
                                      @RequestHeader(value = "token",required = false) @ApiParam("token令牌") String bAuthToken) throws Exception {
        return authorizationUserService.checkUserByQYWeChat(authDto.getCode(),authDto.getRedisToken(),bAuthToken,Integer.parseInt(authDto.getTime()),authDto.getIsAuth());
    }
    /**
     * 获取token
     * @param authorizationDto
     * @return
     */
    @ApiOperation(value = "钉钉获取token")
    @PostMapping("/getDingDingToken")
    @ResponseBody
    public Result getDingDingToken(@RequestBody AuthorizationDto authorizationDto) throws Exception {
        return authorizationUserService.getDingDingToken(authorizationDto);
    }

    @PostMapping(value = "authUserByQYApp",produces = "application/json")
    @ApiOperation(value = "企业微信应用授权上网")
    @ResponseBody
    public Result authUserByQYApp(@RequestBody QyAuth auth) throws Exception {
        log.info("auth--->:"+auth);
        return authorizationUserService.authUserByQYApp(auth.getCode(),auth.getBAuthToken(),auth.getRedisToken());
    }

    @GetMapping(value = "saveParam", produces = "application/json")
    @ApiOperation(value = "参数存进缓存")
    @ResponseBody
    public Result saveParam(@RequestParam(value = "apMac", required = false) String apMac,
                            @RequestParam(value = "ssid", required = false) String ssid,
                            @RequestParam(value = "uAddress", required = false) String uAddress,
                            @RequestParam(value = "uMac", required = false) String uMac,
                            @RequestParam(value = "nodeIp", required = false) String nodeIp,
                            @RequestParam(value = "programmeInfoBindId", required = false) String programmeInfoBindId) throws Exception {
        log.info("apMac:"+apMac);
        log.info("ssid:"+ssid);
        log.info("uAddress:"+uAddress);
        log.info("uMac:"+uMac);
        log.info("nodeIp:"+nodeIp);
        log.info("programmeInfoBindId:"+programmeInfoBindId);
        AuthorizationDto authDto = new AuthorizationDto();
        authDto.setApmac(apMac);
        authDto.setSsid(ssid);
        authDto.setUaddress(uAddress);
        authDto.setUmac(uMac);
        authDto.setNodeIp(nodeIp);
        authDto.setProgrammeInfoBindId(programmeInfoBindId);
        log.info("saveParam--->",JsonXMLUtils.obj2json(authDto));
        return authorizationUserService.saveParam(authDto);
    }

    public static  final String authUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base&state=#wechat_redirect";
    @RequestMapping({"/h5/oauthUrl"})
    @ResponseBody
    Result oauthUrl(@RequestParam("programmeInfoBindId") String programmeInfoBindId, @RequestParam("oauth_callback") String oauthCallback) throws UnsupportedEncodingException {
        Map resData = new HashMap();
        log.info("programmeInfoBindId-->{}",programmeInfoBindId);
        //普通应用
        ProgrammeApiBind programmeApiBind = programmeApiBindDao.queryById(programmeInfoBindId);
        if (null == programmeApiBind) {
            return Result.failure("无绑定信息");
        }
        if (programmeApiBind.getCompanyInfoId() == null || "".equals(programmeApiBind.getCompanyInfoId())) {
            return Result.failure("无企业id");
        }
        CompanyInfo companyInfo = companyInfoDao.queryById(programmeApiBind.getCompanyInfoId());
        if (null == companyInfo) {
            return Result.failure("无企业信息");
        }
        String oauthRedirectUrl =  URLEncoder.encode(oauthCallback,"utf-8");
        String oauthUrl = String.format(authUrl,companyInfo.getCorpId(),oauthRedirectUrl);
        resData.put("oauth_url",oauthUrl);
        return  Result.ok().setData(resData);
    }
}
